<!-- @format -->

<template>
  <div class="pg-dashboard">
    <Divider dashed>数据统计</Divider>
    <div :data-watch="this.watchTimeSelect"></div>
    <el-header direction="horizontal" style="text-align: right;">
      <div class="header">
        <div class="date-time-range-picker">
          <DatetimeRangePicker :startAt.sync="status.startAt" :endAt.sync="status.endAt" />
        </div>
      </div>
    </el-header>
    <Row :gutter="10" class="pg-dashboard-top">
      <Col span="6">
        <div class="next-card">
          <div class="next-card-body">
            <div class="next-card-content">
              <div class="main_card">
                <div class="content">
                  <div class="content-item max_50">
                    <span class="balloon-trigger title">{{ apiDataView.errorCount }}</span>
                    <div class="text"><span>API错误数</span></div>
                  </div>
                  <div class="vertical_line"></div>
                  <div class="content-item max_50">
                    <span class="balloon-trigger title">{{ apiDataView.successRate }}</span>
                    <div class="text"><span>API请求成功率</span></div>
                  </div>
                </div>
                <!-- <div class="compare">
                  <div class="compare_item">
                    <span>周同比：</span><span class="error">--%<i class="cocofont coco-rise"></i></span>
                  </div>
                  <div class="vertical_line"></div>
                  <div class="compare_item">
                    <span>周同比：</span><span class="success">0%<i class="cocofont coco-rise"></i></span>
                  </div>
                </div> -->
              </div>
              <div class="increase">
                <span>请求耗时大于1秒</span><span class="error">{{ apiDataView.MoOneSecondCount }}</span>
              </div>
            </div>
          </div>
        </div>
      </Col>
      <Col span="12">
        <div class="next-card">
          <div class="next-card-body">
            <div class="next-card-content">
              <div class="main_card">
                <div class="content">
                  <div class="content-item max_50">
                    <span class="balloon-trigger title"><countTo separator="," :startVal="oldPV" :endVal="PV" :duration="2000"></countTo></span>
                    <div class="text"><span>PV</span></div>
                  </div>
                  <div class="vertical_line"></div>
                  <div class="content-item max_50">
                    <span class="balloon-trigger title">{{ logDataView.project }}</span>
                    <div class="text"><span>UV</span></div>
                  </div>
                </div>
              </div>
              <div class="increase">
                <span>云监控累计接入项目数</span><span class="error">{{ logDataView.project }}</span>
              </div>
            </div>
          </div>
        </div>
      </Col>
      <Col span="6">
        <div class="next-card card-right">
          <div class="next-card-body">
            <div class="next-card-content">
              <div class="main_card">
                <div class="content">
                  <div class="content-item">
                    <span class="balloon-trigger noclick-title">
                      {{ indicatorDataView.value }}
                      ms</span
                    >
                    <div class="text"><span>最近一次首次渲染耗时</span></div>
                  </div>
                </div>
                <div class="compare"></div>
              </div>
              <!-- <div class="increase">
                <span>云监控累计接入项目数</span><span class="error">{{ logDataView.project }}</span>
              </div> -->
            </div>
          </div>
        </div>
      </Col>
    </Row>
    <!-- <Card style="width:220px;box-shadow: -5px 5px 10px;border-radius: 3px;">
      <div>
        <img src="~/src/assets/images/logo-min.png" width="70px" />
        <div>
          
        </div>
      </div>
    </Card> -->

    <!-- <Row :gutter="10">
      <Col span="6" v-for="(item, index) in overview" :key="index">
        <i-circle :dashboard="!index" :size="180" :trail-width="4" :stroke-width="5" :percent="getPercent(logDataView.current[item.key], logDataView.count[item.key])" stroke-linecap="square" :stroke-color="item.color">
          <div class="circle-custom">
            <h3>
              <countTo separator="," :startVal="logDataView.old[item.key]" :endVal="logDataView.count[item.key]" :duration="2000"></countTo>
            </h3>
            <p>今日{{ item.name }}总数</p>
            <span
              >当前项目占比<i>{{ getPercent(logDataView.current[item.key], logDataView.count[item.key]) }}%</i></span
            >
          </div>
        </i-circle>
      </Col>
    </Row>
    <Divider dashed>数据总量排行</Divider>
    <div ref="data-total-line" class="data-rank-line"></div>
    <Divider dashed>错误总量排行</Divider>
    <Row :gutter="16">
      <Col span="24">
        <div ref="data-error-line" class="data-rank-line"></div>
      </Col>
    </Row>
    <Divider dashed>性能排行</Divider>
    <Row :gutter="16">
      <Col span="12">
        <!-- 首次渲染耗时 -->
    <!-- <div ref="data-perf-fpt-line" class="data-rank-line"></div>
      </Col> -->
    <!-- <Col span="12">
        <!-- 首次可交互耗时 -->
    <!-- <div ref="data-perf-tti-line" class="data-rank-line"></div>
      </Col> -->
    <!-- </Row>
    <Row :gutter="16">
      <Col span="12">
        <!-- 首包时间 -->
    <!-- <div ref="data-perf-ftcp-line" class="data-rank-line"></div>
      </Col>
    </Row>  -->
  </div>
</template>
<script>
  import _ from 'lodash'
  import echart from 'echarts'
  import countTo from 'vue-count-to'
  import moment from 'moment'
  import DATE_FORMAT from 'src/constants/date_format'
  import DatetimeRangePicker from 'src/components/datetime-range-picker.vue'
  import { dotDataLineOptions } from './conf'
  import { getProjectUV, getProjectLog, getPerfLog, getProjectPV } from 'src/api/dashboard'
  import { fetchApiOverview, fetchIndicatorOverview } from 'src/api/performance'

  const defautColor = '#43a3fb'
  const errorColor = '#ed4014'
  const perfColor = '#19be6b'
  const productColor = '#ff9900'

  export default {
    components: {
      countTo,
      DatetimeRangePicker
    },
    data() {
      return {
        status: {
          startAt: moment()
            .subtract(1, DATE_FORMAT.UNIT.DAY)
            .startOf(DATE_FORMAT.UNIT.DAY)
            .unix(),
          endAt: moment()
            .endOf(DATE_FORMAT.UNIT.MINUTE)
            .unix()
        },
        timer: null,
        UV: 0,
        oldUV: 0,
        PV: 0,
        oldPV: 0,
        overview: [
          {
            name: '数据',
            key: 'total',
            color: defautColor
          },
          {
            name: 'error',
            key: 'error',
            color: errorColor
          },
          {
            name: 'perf',
            key: 'perf',
            color: perfColor
          },
          {
            name: 'product',
            key: 'product',
            color: productColor
          }
        ],
        perfData: {
          current: {},
          list: []
        },
        apiDataView: {
          errorCount: 0,
          successRate: '100%',
          MoOneSecondCount: 0
        },
        indicatorDataView: {
          name: '',
          value: 0
        },
        logDataView: {
          old: {
            error: 0,
            perf: 0,
            product: 0,
            total: 0
          },
          count: {
            error: 0,
            perf: 0,
            product: 0,
            total: 0
          },
          current: {
            error: 0,
            perf: 0,
            product: 0,
            total: 0,
            name: '',
            errorRadio: ''
          },
          list: [],
          project: 1
        },
        stackAreaPic1: null,
        stackAreaPic2: null,
        stackAreaPic3: null,
        stackAreaPic4: null,
        stackAreaPic5: null
      }
    },
    async mounted() {
      // this.stackAreaPic1 = echart.init(this.$refs['data-total-line'])
      // this.stackAreaPic2 = echart.init(this.$refs['data-error-line'])
      // this.stackAreaPic3 = echart.init(this.$refs['data-perf-fpt-line'])
      // this.stackAreaPic4 = echart.init(this.$refs['data-perf-tti-line'])
      // this.stackAreaPic5 = echart.init(this.$refs['data-perf-ftcp-line'])
      await this.getData()
      // this.drawLine()
      this.timer = setInterval(async () => {
        await this.getData()
        // this.drawLine()
      }, 10000)
    },
    beforeDestroy() {
      this.timer && clearInterval(this.timer)
    },
    methods: {
      drawLine() {
        const { current } = this.logDataView
        this.stackAreaPic1.setOption(dotDataLineOptions(this.getStackAreaData('total')), true)
        this.stackAreaPic2.setOption(dotDataLineOptions(this.getStackAreaData('error')), true)
        this.stackAreaPic3.setOption(dotDataLineOptions(this.getStackAreaData('fpt')), true)
        this.stackAreaPic4.setOption(dotDataLineOptions(this.getStackAreaData('tti')), true)
        this.stackAreaPic5.setOption(dotDataLineOptions(this.getStackAreaData('ftcp')), true)
      },
      async getData() {
        await this.getApiData()
        // await this.getLogData()
        // await this.getPerfData()
        // await this.getUV()
        await this.getPV()
        await this.getIndicatorData()
      },
      // 获取UV数据
      async getUV() {
        let data = await getProjectUV()
        this.oldUV = this.UV
        this.UV = _.get(data, ['data'], 0)
      },
      // 获取UV数据
      async getPV() {
        let data = await getProjectPV({
          st: this.status.startAt,
          et: this.status.endAt
        })
        this.oldPV = this.PV
        this.PV = _.get(data, ['data'], 0)
      },

      // 获取今日日志数量
      async getLogData() {
        let data = await getProjectLog()
        let res = _.get(data, 'data', {
          count: {},
          current: {},
          list: [],
          project: 1
        })
        this.logDataView = {
          ...res,
          old: _.get(this.logDataView, ['count'], {})
        }
      },
      // 获取ApI数量
      async getApiData() {
        let data = await fetchApiOverview({
          st: this.status.startAt,
          et: this.status.endAt,
          summaryBy: 'minute'
        })
        let res = _.get(data, 'data', {})
        this.apiDataView = {
          ...res
        }
      },
      // 获取指标
      async getIndicatorData() {
        let data = await fetchIndicatorOverview({
          st: this.status.startAt,
          et: this.status.endAt,
          indicatorList: ['first_render_ms']
        })
        let res = _.get(data, 'data', [])
        if (res.length > 1) {
          this.indicatorDataView = {
            value: res[res.length - 1].sum_indicator_value,
            name: res[res.length - 1].indicator
          }
        } else {
          this.indicatorDataView = {
            value: '--',
            name: ''
          }
        }
      },

      // 获取性能排行数据
      async getPerfData() {
        let data = await getPerfLog()
        this.perfData = _.get(data, 'data', {
          current: {},
          list: []
        })
      },
      // 格式化图表数据
      getStackAreaData(type) {
        let { current, list, count } = this.logDataView
        let title = ''
        let subtext = ''
        let series = []
        let color = ['#61a0a8', '#2f4554', '#c23531']
        let legend = {
          show: true,
          data: []
        }
        let tooltip = {
          trigger: 'axis',
          axisPointer: {
            // 坐标轴指示器，坐标轴触发有效
            type: 'shadow' // 默认为直线，可选为：'line' | 'shadow'
          }
        }
        let xAxis = {
          type: 'category',
          axisLabel: {
            rotate: 60
          },
          data: ['SAAS', '数量', '云设计']
        }

        // 数据总量排行
        if (type === 'total') {
          title = '数据总量Top10'
          let rank = _.findIndex(list, (item) => item.id === current.id) + 1
          let rankData = _.find(list, (item) => item.id === current.id)
          let top10 = _.slice(list, 0, 10)
          subtext = `${current.name || '未知'}：第${rank}位`
          if (rank > 10) {
            top10.push(rankData)
          }
          _.set(legend, ['data'], ['product', 'perf', 'error'])
          _.set(legend, ['selected', 'product'], false)
          _.set(
            xAxis,
            ['data'],
            top10.map((item) => item.name)
          )

          series = _.get(legend, 'data', []).map((type) => {
            let data = {
              name: type,
              type: 'bar',
              stack: '总量',
              label: {
                normal: {
                  show: true,
                  position: 'insideRight',
                  rotate: -30
                }
              },
              data: top10.map((item) => item[type])
            }
            return data
          })
        }
        // 错误总数排行
        if (type === 'error') {
          color = [errorColor]
          title = '错误总量Top10'
          list = list.sort((a, b) => b.error - a.error)
          let rank = _.findIndex(list, (item) => item.id === current.id) + 1
          let rankData = _.find(list, (item) => item.id === current.id)
          let top10 = _.slice(list, 0, 10)
          subtext = `${current.name || '未知'}：第${rank}位`
          if (rank > 10) {
            top10.push(rankData)
          }
          _.set(legend, ['data'], ['error'])
          _.set(legend, ['show'], false)
          _.set(
            xAxis,
            ['data'],
            top10.map((item) => item.name)
          )

          series = _.get(legend, 'data', []).map((type) => {
            let data = {
              name: type,
              type: 'bar',
              stack: '总量',
              label: {
                normal: {
                  show: false,
                  position: 'insideRight'
                }
              },
              data: top10.map((item) => item[type])
            }
            return data
          })

          let tooltipFormatter = (params) => {
            const { value, name, dataIndex } = _.get(params, [0], {})
            let str = `<div>
            <p>占错误总量比：${this.getPercent(value, count.error)}%</p>
            <p>占自身数据总量比：${this.getPercent(value, _.get(top10, [dataIndex, 'total'], 1))}%</p>
            <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#c23531;"></span>${this.toThousands(value)}
          </div>`
            return str
          }
          _.set(tooltip, ['formatter'], tooltipFormatter)
        }
        // 性能首次渲染时间排行
        if (type === 'fpt') {
          list = _.get(this.perfData, 'list', [])
          current = _.get(this.perfData, 'current', [])
          color = [perfColor]
          title = `首次渲染耗时：Bottom10`
          list = list.sort((a, b) => b.fpt - a.fpt)

          let rank = _.findIndex(list, (item) => item.id === current.id) + 1
          let rankData = _.find(list, (item) => item.id === current.id)
          let top10 = _.slice(list, 0, 10)

          subtext = `第${rank}位`
          if (rank > 10) {
            top10.push(rankData)
          }
          _.set(legend, ['data'], ['fpt'])
          _.set(legend, ['show'], false)
          _.set(
            xAxis,
            ['data'],
            top10.map((item) => item.name)
          )

          series = _.get(legend, 'data', []).map((type) => {
            let data = {
              name: type,
              type: 'bar',
              stack: '总量',
              label: {
                normal: {
                  show: false,
                  position: 'insideRight'
                }
              },
              data: top10.map((item) => item[type])
            }
            return data
          })

          let tooltipFormatter = (params) => {
            const { value, name, dataIndex } = _.get(params, [0], {})
            let str = `<div>
            <p>${name}</p>
            <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#c23531;"></span>${value.toFixed(2)}ms
          </div>`
            return str
          }
          _.set(tooltip, ['formatter'], tooltipFormatter)
        }
        // 性能首次可交互时间排行
        if (type === 'tti') {
          list = _.get(this.perfData, 'list', [])
          current = _.get(this.perfData, 'current', [])

          color = [perfColor]
          title = `首次可交互耗时：Bottom10`
          list = list.sort((a, b) => b.tti - a.tti)

          let rank = _.findIndex(list, (item) => item.id === current.id) + 1
          let rankData = _.find(list, (item) => item.id === current.id)
          let top10 = _.slice(list, 0, 10)

          subtext = `第${rank}位`
          if (rank > 10) {
            top10.push(rankData)
          }
          _.set(legend, ['data'], ['tti'])
          _.set(legend, ['show'], false)
          _.set(
            xAxis,
            ['data'],
            top10.map((item) => item.name)
          )

          series = _.get(legend, 'data', []).map((type) => {
            let data = {
              name: type,
              type: 'bar',
              stack: '总量',
              label: {
                normal: {
                  show: false,
                  position: 'insideRight'
                }
              },
              data: top10.map((item) => item[type])
            }
            return data
          })

          let tooltipFormatter = (params) => {
            const { value, name, dataIndex } = _.get(params, [0], {})
            let str = `<div>
            <p>${name}</p>
            <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#c23531;"></span>${value.toFixed(2)}ms
          </div>`
            return str
          }
          _.set(tooltip, ['formatter'], tooltipFormatter)
        }
        // 性能首包时间排行
        if (type === 'ftcp') {
          list = _.get(this.perfData, 'list', [])
          current = _.get(this.perfData, 'current', [])

          color = [perfColor]
          title = `首包时间：Bottom10 `
          list = list.sort((a, b) => b.ftcp - a.ftcp)

          let rank = _.findIndex(list, (item) => item.id === current.id) + 1
          let rankData = _.find(list, (item) => item.id === current.id)
          let top10 = _.slice(list, 0, 10)

          subtext = `第${rank}位`
          if (rank > 10) {
            top10.push(rankData)
          }
          _.set(legend, ['data'], ['ftcp'])
          _.set(legend, ['show'], false)
          _.set(
            xAxis,
            ['data'],
            top10.map((item) => item.name)
          )

          series = _.get(legend, 'data', []).map((type) => {
            let data = {
              name: type,
              type: 'bar',
              stack: '总量',
              label: {
                normal: {
                  show: false,
                  position: 'insideRight'
                }
              },
              data: top10.map((item) => item[type])
            }
            return data
          })

          let tooltipFormatter = (params) => {
            const { value, name, dataIndex } = _.get(params, [0], {})
            let str = `<div>
            <p>${name}</p>
            <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#c23531;"></span>${value.toFixed(2)}ms
          </div>`
            return str
          }
          _.set(tooltip, ['formatter'], tooltipFormatter)
        }
        return {
          title,
          subtext,
          color,
          legend,
          xAxis,
          series,
          tooltip
        }
      },
      // 转化为百分数，保留两位小数
      getPercent(num, total) {
        if (!num || !total) return 0
        return Math.round((num / total) * 10000) / 100.0
      },
      // 千分位表示
      toThousands(num) {
        return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
      }
    },
    computed: {
      watchTimeSelect() {
        this.getData()
        return `${this.status.startAt}-${this.status.endAt}`
      }
    }
  }
</script>
<style lang="less">
  .pg-dashboard-top {
    display: flex;
    justify-content: space-between;
    margin-bottom: 24px;
  }
  .next-card {
    font: 12px/1.5 Arial, Helvetica, Verdana, PingFang SC, Microsoft Yahei, sans-serif;
    font-weight: 400;
    margin-top: 12px;
    width: 100%;
    font-size: 12px;
    color: #9b9ea0;
    padding: 20px 4px;
    min-width: 100px;
    border: 1px solid #ebecec;
    border-radius: 0;
    -webkit-box-shadow: none;
    box-shadow: none;
    background: #fff;
    overflow: hidden;
    &-body {
      padding-top: 12px;
      padding-bottom: 12px;
      padding-left: 16px;
      padding-right: 16px;
      .next-card-content {
        box-sizing: border-box;
        overflow: hidden;
        transition: all 0.3s ease;
        position: relative;
        .main_card {
          .content {
            text-align: center;
            position: relative;
            margin-bottom: 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            .content-item {
              flex: 1;
              text-align: center;
              .title {
                cursor: pointer;
                text-overflow: ellipsis;
                overflow: hidden;
                white-space: nowrap;
                font-size: 25px;
                line-height: 36px;
                font-weight: 700;
                color: #373d41;
              }
              .noclick-title {
                font-size: 28px;
                line-height: 42px;
                font-weight: 700;
                color: #373d41;
              }
              .text {
                font-weight: 700;
              }
            }
            .vertical_line {
              background: #eee;
              height: 20px;
              width: 1px;
              margin: 0 10px;
            }
            .max_50 {
              max-width: calc(50% - 20px);
            }
          }
          .compare {
            display: flex;
            justify-content: space-between;
            align-items: center;
            .compare_item {
              flex: 1;
              text-align: center;
              .success {
                color: #38c58d;
                cursor: pointer;
              }
              .error {
                color: #e55130;
                cursor: pointer;
              }
            }
            .vertical_line {
              margin-bottom: 10px;
              height: 20px;
              width: 1px;
              margin: 0 10px;
            }
          }
        }
        .increase {
          text-align: center;
          span {
          }
          .error {
            color: #e55130;
            cursor: pointer;
            margin-left: 5px;
          }
        }
      }
    }
  }
  .card-right {
    width: 100%;
    font-size: 12px;
    color: #9b9ea0;
    padding: 20px 4px;
    height: calc(100% - 7px);
  }
  .ivu-table td.table-error-col {
    background-color: red;
    color: #fff;
  }
  .data-rank-line {
    height: 400px;
    width: 80%;
  }
  .circle-custom {
    & h3 {
      color: #3f414d;
      font-size: 24px;
      font-weight: normal;
    }
    & p {
      color: #657180;
      font-size: 12px;
      margin: 10px 0 15px;
    }
    & > span {
      display: block;
      padding-top: 15px;
      color: #657180;
      font-size: 12px;
      &:before {
        content: '';
        display: block;
        width: 50px;
        height: 1px;
        margin: 0 auto;
        background: #e0e3e6;
        position: relative;
        top: -15px;
      }
    }
    & span i {
      font-style: normal;
      color: #3f414d;
    }
  }
</style>
